#include "firstwindow.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
#include "choosecitydialog.h"
#include "customcontrol.h"
#include "flightscheckwindow.h"
#include "interfacemanager.h"
#include "models.h"
#include "system.h"
#include "ui_firstwindow.h"
#include <iostream>


QList<Flight> Flight::flightsList;
QList<Flight> Flight::flightsList_return;

SelectedDate selectedDate;
bool one_way = true;

FirstWindow::FirstWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::FirstWindow)
    , manager(new QNetworkAccessManager(this))
{
    ui->setupUi(this);

    // 为 QLineEdit 控件添加点击信号
    CustomControl::addClickSignal(ui->DepartEdit);
    CustomControl::addClickSignal(ui->DepartEdit_2);
    CustomControl::addClickSignal(ui->ApartEdit);
    CustomControl::addClickSignal(ui->ApartEdit_2);
    CustomControl::addClickSignal(ui->DateEdit);
    CustomControl::addClickSignal(ui->DepartDateEdit);
    CustomControl::addClickSignal(ui->ApartDateEdit);

    // 连接信号到槽
    connectLineEditSignals(ui->DepartEdit);
    connectLineEditSignals(ui->DepartEdit_2);
    connectLineEditSignals(ui->ApartEdit);
    connectLineEditSignals(ui->ApartEdit_2);
    connectLineEditSignals(ui->DateEdit);
    connectLineEditSignals(ui->DepartDateEdit);
    connectLineEditSignals(ui->ApartDateEdit);
    connectLineEditSignals(ui->DateEdit);

    //页面自动选择今日日期
    QDate today = selectedDate.departdate;
    QString dateStr = today.toString("yyyy-MM-dd");
    ui->DateEdit->setText(dateStr);
    ui->DepartDateEdit->setText(dateStr);
    // 创建对话框实例
    cityDialog = new ChooseCityDialog(this);
    cityDialog->setWindowFlags(Qt::Popup); // 设置为 Popup 类型
    cityDialog->hide();
    //创建日期选择对话框
    dateDialog = new CalendarDialog(this);
    dateDialog->setWindowFlags(Qt::Popup); // 设置为 Popup 类型
    dateDialog->hide();

    // 安装全局事件过滤器
    qApp->installEventFilter(this);
}

FirstWindow::~FirstWindow()
{
    delete ui;
}

void FirstWindow::on_toCheckbutton_clicked()
{
    // 从 QLineEdit 控件读取数据
    QString departure = ui->DepartEdit->text();  // 获取出发地
    QString destination = ui->ApartEdit->text(); // 获取目的地
    QString departdate = ui->DateEdit->text();
    QString e_departure = ChooseCityDialog::cityMapTranslations[departure];
    QString e_destination = ChooseCityDialog::cityMapTranslations[destination];
    one_way=true;
    // 创建一个 JSON 对象，封装请求体
    QJsonObject json;
    json["departure"] = e_departure;
    json["destination"] = e_destination;
    json["departureTime"] = departdate;

    qDebug() << "Preparing request data:" << json;

    // 将 JSON 对象转换为 JSON 文档
    QJsonDocument doc(json);
    QByteArray data = doc.toJson();

    // 设置请求头
    QNetworkRequest request(QUrl("http://127.0.0.1:8080/api/flights/search")); // 替换为你的 API URL
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    // 发送 POST 请求
    QNetworkReply *reply = manager->post(request, data);
    reply->setProperty("requestType", "go");

    // 连接请求完成信号
    connect(reply, &QNetworkReply::finished, this, &FirstWindow::onFlightSearchRequestFinished);
}
void FirstWindow::on_toCheckbutton_2_clicked()
{
    // 从 QLineEdit 控件读取数据
    QString departure = ui->DepartEdit_2->text();  // 获取出发地
    QString destination = ui->ApartEdit_2->text();  // 获取目的地
    QString departdate = ui->DepartDateEdit->text();//出发日期
    QString returndate = ui->ApartDateEdit->text();//返回日期
    QString e_departure = ChooseCityDialog::cityMapTranslations[departure];
    QString e_destination = ChooseCityDialog::cityMapTranslations[destination];
    one_way=false;

    // 创建一个 JSON 对象，封装请求体
    QJsonObject json_go,json_return;
    json_go["departure"] = e_departure;
    json_go["destination"] = e_destination;
    json_go["departureTime"] = departdate;

    json_return["departure"] = e_destination;
    json_return["destination"] = e_departure;
    json_return["departureTime"] = returndate;

    qDebug() << "Preparing request data:" << json_go<<"and"<<json_return;

    // 将 JSON 对象转换为 JSON 文档
    QJsonDocument doc_go(json_go);
    QJsonDocument doc_return(json_return);
    QByteArray data_go = doc_go.toJson();
    QByteArray data_return = doc_return.toJson();

    // 设置请求头
    QNetworkRequest request_go(QUrl("http://127.0.0.1:8080/api/flights/search"));
    request_go.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QNetworkRequest request_return(QUrl("http://127.0.0.1:8080/api/flights/search"));
    request_return.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    // 发送 POST 请求
    QNetworkReply *reply_go = manager->post(request_go, data_go);
    reply_go->setProperty("requestType", "go");

    QNetworkReply *reply_return = manager->post(request_return, data_return);
    reply_return->setProperty("requestType", "return");

    // 连接请求完成信号
    connect(reply_go, &QNetworkReply::finished, this, &FirstWindow::onFlightSearchRequestFinished);
    connect(reply_return, &QNetworkReply::finished, this, &FirstWindow::onFlightSearchRequestFinished);
}

void FirstWindow::onFlightSearchRequestFinished()
{
    QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
    if (!reply) return;

    // 如果请求失败，输出错误信息
    if (reply->error() != QNetworkReply::NoError) {
        QString errorString = reply->errorString();
        qDebug() << "Request failed with error:" << errorString;
        QMessageBox::critical(this, "Error", "Flight search request failed: " + errorString);
        reply->deleteLater();
        return;
    }

    // 获取请求类型
    QString requestType = reply->property("requestType").toString();

    // 请求成功，处理响应数据
    QByteArray response = reply->readAll();
    QJsonDocument doc = QJsonDocument::fromJson(response);
    QJsonObject jsonResponse = doc.object();

    int code = jsonResponse["code"].toInt();
    if (code == 200) {
        // 查询成功，获取航班数据
        QJsonArray flights = jsonResponse["data"].toArray();
        if (flights.isEmpty()) {
            QMessageBox::warning(this, "No Flights", "No flights found for the given criteria.");
            qDebug() << "No flights found for the given search criteria.";
        } else {
            QList<Flight> &targetList = (requestType == "go") ? Flight::flightsList :  Flight::flightsList_return;
            targetList.clear(); // 清空目标列表，确保不混入旧数据
            foreach (const QJsonValue &value, flights) {
                QJsonObject flight = value.toObject();

                QDateTime departureDateTime = QDateTime::fromString(flight["departureTime"].toString(), "yyyy-MM-ddTHH:mm:ss.zzz");
                QDateTime arrivalDateTime = QDateTime::fromString(flight["arrivalTime"].toString(), "yyyy-MM-ddTHH:mm:ss.zzz");
                QString departureDate = departureDateTime.isValid() ? departureDateTime.toString("yyyy-MM-dd") : "";
                QString arrivalDate = arrivalDateTime.isValid() ? arrivalDateTime.toString("yyyy-MM-dd") : "";

                Flight flightData(
                    flight.contains("id") ? flight["id"].toInt() : -1,
                    flight.contains("flightNumber") ? flight["flightNumber"].toString() : "",
                    flight.contains("departure") ? ChooseCityDialog::englishToChineseMap.value(flight["departure"].toString(), "") : "",
                    flight.contains("destination") ? ChooseCityDialog::englishToChineseMap.value(flight["destination"].toString(), "") : "",
                    flight.contains("departureAirport") ? flight["departureAirport"].toString() : "",
                    flight.contains("destinationAirport") ? flight["destinationAirport"].toString() : "",
                    !departureDate.isEmpty() ? departureDateTime : QDateTime(),
                    !arrivalDate.isEmpty() ? arrivalDateTime : QDateTime(),
                    flight.contains("firstClassSeats") ? flight["firstClassSeats"].toInt() : 0,
                    flight.contains("economyClassSeats") ? flight["economyClassSeats"].toInt() : 0,
                    flight.contains("firstClassPrice") ? flight["firstClassPrice"].toDouble() : 0.0,
                    flight.contains("economyClassPrice") ? flight["economyClassPrice"].toDouble() : 0.0,
                    flight.contains("airlineCompany") ? flight["airlineCompany"].toString() : "",
                    flight.contains("aircraftModel") ? flight["aircraftModel"].toString() : ""
                    );

                // 判断是否匹配出发时间
                QString departureTimeStr = (requestType == "go") ?ui->DepartDateEdit->text():ui->ApartDateEdit->text();
                if (departureDate == departureTimeStr) {
                    // 填充 Flight 类数据
                    Flight flightData(
                        flight.contains("id") ? flight["id"].toInt()
                                              : -1, // 如果缺少 id，则使用默认值 -1
                        flight.contains("flightNumber") ? flight["flightNumber"].toString()
                                                        : "", // 如果缺少航班号，则传空字符串
                        flight.contains("departure")
                            ? ChooseCityDialog::englishToChineseMap
                                  .value(flight["departure"].toString(), "")
                            : "", // 如果缺少出发地，则传空字符串
                        flight.contains("destination")
                            ? ChooseCityDialog::englishToChineseMap
                                  .value(flight["destination"].toString(), "")
                            : "", // 如果缺少目的地，则传空字符串
                        flight.contains("departureAirport") ? flight["departureAirport"].toString()
                                                            : "", // 如果缺少出发机场，则传空字符串
                        flight.contains("destinationAirport")
                            ? flight["destinationAirport"].toString()
                            : "", // 如果缺少目的机场，则传空字符串
                        // 注意两个时间如果传的是日期+时刻的QDateTime类型，如果在别的页面想只显示日期，还要像上面那样提取一次再使用
                        !departureDate.isEmpty()
                            ? departureDateTime
                            : QDateTime(), // 如果缺少出发时间，则传 QDateTime()（空时间）
                        !arrivalDate.isEmpty()
                            ? arrivalDateTime
                            : QDateTime(), // 如果缺少到达时间，则传 QDateTime()（空时间）
                        flight.contains("firstClassSeats") ? flight["firstClassSeats"].toInt()
                                                           : 0, // 如果缺少头等舱座位，则传 0
                        flight.contains("economyClassSeats") ? flight["economyClassSeats"].toInt()
                                                             : 0, // 如果缺少经济舱座位，则传 0
                        flight.contains("firstClassPrice") ? flight["firstClassPrice"].toDouble()
                                                           : 0.0, // 如果缺少头等舱票价，则传 0.0
                        flight.contains("economyClassPrice")
                            ? flight["economyClassPrice"].toDouble()
                            : 0.0, // 如果缺少经济舱票价，则传 0.0
                        flight.contains("airlineCompany") ? flight["airlineCompany"].toString()
                                                          : "", // 如果缺少航空公司，则传空字符串
                        flight.contains("aircraftModel") ? flight["aircraftModel"].toString()
                                                         : "" // 如果缺少飞机型号，则传空字符串
                        );

                    targetList.append(flightData); // 将每个 Flight 对象添加到列表
                    qDebug() << "Total flights in list:" <<targetList.size();

                    // 使用 qDebug 输出类对象的每个字段
                    qDebug() << "Flight ID:" << flightData.id;
                    qDebug() << "Flight Number:" << flightData.flightNumber;
                    qDebug() << "Departure:" << flightData.departure;
                    qDebug() << "Destination:" << flightData.destination;
                    qDebug() << "Departure Airport:" << flightData.departureAirport;  // 输出出发机场
                    qDebug() << "Destination Airport:" << flightData.destinationAirport;  // 输出到达机场
                    qDebug() << "Departure Time:" << flightData.departureTime;
                    qDebug() << "Arrival Time:" << flightData.arrivalTime;
                    qDebug() << "First Class Seats:" << flightData.firstClassSeats;
                    qDebug() << "Economy Class Seats:" << flightData.economyClassSeats;
                    qDebug() << "First Class Price:" << flightData.firstClassPrice;
                    qDebug() << "Economy Class Price:" << flightData.economyClassPrice;
                    qDebug() << "Airline Company:" << flightData.airlineCompany;
                    qDebug() << "Aircraft Model:" << flightData.aircraftModel;  // 输出飞机型号

                }
            }

            qDebug() << (requestType == "go" ? "Go flights list size:" : "Return flights list size:") << targetList.size();
        }
    } else {
        QMessageBox::warning(this, "Error", "Flight search failed. Code: " + QString::number(code));
        qDebug() << "Flight search failed. Response code:" << code;
    }

    reply->deleteLater();
    createflightcheckwindow();
}
void FirstWindow::createflightcheckwindow(){
    InterfaceManager ::instance()->unregisterPage("/MainWindow/First/FlightCheck");
    FlightsCheckWindow *flightscheck = new FlightsCheckWindow();
    InterfaceManager::instance()->registerPage("/MainWindow/First/FlightCheck", flightscheck);
    connect(this,
            &FirstWindow::triggerFunction,
            flightscheck,
            &FlightsCheckWindow::onTriggerFunction); // 连接信号到槽
    qDebug() << "Before emitting signal";
    emit triggerFunction(); // 发射信号
    qDebug() << "Signal emitted";

    InterfaceManager::instance()->switchToPage("/MainWindow/First/FlightCheck");
}

void FirstWindow::on_toLogbotton_clicked()
{
    InterfaceManager::instance()->switchToPage("/MainWindow/First/Log");
}

void FirstWindow::on_toEnrollbotton_clicked()
{
    InterfaceManager::instance()->switchToPage("/MainWindow/First/Enroll");
}

void FirstWindow::on_pushButton_clicked()
{
    InterfaceManager::instance()->switchToPage("/MainWindow/First/Order");
}

void FirstWindow::connectLineEditSignals(QLineEdit *lineEdit)
{
    connect(lineEdit, &QLineEdit::customContextMenuRequested, this, [this, lineEdit]() {
        if (lineEdit == ui->DepartEdit || lineEdit == ui->DepartEdit_2) {
            handleLineEditClick(lineEdit); // 处理出发地相关控件
        } else if (lineEdit == ui->ApartEdit || lineEdit == ui->ApartEdit_2) {
            handleLineEditClick(lineEdit); // 处理目的地相关控件
        } else if (lineEdit == ui->DateEdit || lineEdit == ui->ApartDateEdit
                   || lineEdit == ui->DepartDateEdit) {
            handleDateEditClick(lineEdit); // 处理目的地相关控件
        }
    });
}

void FirstWindow::handleLineEditClick(QLineEdit *lineEdit)
{
    QPoint globalPos = lineEdit->mapToGlobal(QPoint(lineEdit->width(), lineEdit->height()));

    int dialogWidth = cityDialog->width();
    cityDialog->move(globalPos.x() - dialogWidth, globalPos.y());
    cityDialog->show();

    lineEdit->selectAll();

    if (cityDialog && this) {
        // 解除信号与槽的连接
        disconnect(cityDialog, &ChooseCityDialog::citySelected, nullptr, nullptr);

        if (lineEdit == ui->DepartEdit || lineEdit == ui->DepartEdit_2) {
            connect(cityDialog,
                    &ChooseCityDialog::citySelected,
                    this,
                    [this, lineEdit](const QString &cityName) {
                        updateLineEditWithCity(cityName, lineEdit);
                    });
        } else if (lineEdit == ui->ApartEdit || lineEdit == ui->ApartEdit_2) {
            connect(cityDialog,
                    &ChooseCityDialog::citySelected,
                    this,
                    [this, lineEdit](const QString &cityName) {
                        updateLineEditWithCity(cityName, lineEdit);
                    });
        }
    }
}

void FirstWindow::handleDateEditClick(QLineEdit *lineEdit)
{
    QPoint globalPos = lineEdit->mapToGlobal(QPoint(lineEdit->width(), lineEdit->height()));

    int dialogWidth = dateDialog->width();
    dateDialog->move(globalPos.x() - dialogWidth, globalPos.y());
    dateDialog->show();

    lineEdit->selectAll();

    if (dateDialog && this) {
        // 解除信号与槽的连接
        disconnect(dateDialog, &CalendarDialog::dateSelected, nullptr, nullptr);

        if (lineEdit == ui->DateEdit
            || lineEdit == ui->DepartDateEdit) {
            connect(dateDialog,
                    &CalendarDialog::dateSelected,
                    this,
                    &FirstWindow::updateDateDisplay1);
            //connect(dateDialog, &CalendarDialog::dateSelected, this, &FlightsCheckWindow::receiveDate) ;
        } else if (lineEdit == ui->ApartDateEdit) {
            connect(dateDialog,
                    &CalendarDialog::dateSelected,
                    this,
                    &FirstWindow::updateDateDisplay2);
        }
    }
}

void FirstWindow::updateDateDisplay1(const QDate &date)
{
    // 将选中的日期更新到 QLabel
    selectedDate.departdate = date;
    QString dateStr = selectedDate.departdate.toString("yyyy-MM-dd");
    ui->DateEdit->setText(dateStr); // 更新 QLineEdit
    ui->DepartDateEdit->setText(dateStr);
    // connect(this, &CalendarDialog::dateSelected, FlightsCheckWindow, &FlightsCheckWindow::receiveDate);
    // emit dateSelected(selectedDate);
}
void FirstWindow::updateDateDisplay2(const QDate &date)
{
    // 将选中的日期更新到 QLabel
    selectedDate.apartdate = date;
    QString dateStr = selectedDate.apartdate.toString("yyyy-MM-dd");
    ui->ApartDateEdit->setText(dateStr); // 更新 QLineEdit
}

void FirstWindow::updateLineEditWithCity(const QString &cityName, QLineEdit *lineEdit)
{
    lineEdit->setText(cityName);
    cityDialog->hide();
}

bool FirstWindow::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == ui->DepartEdit || watched == ui->DepartEdit_2) {
        if (event->type() == QEvent::KeyPress) {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

            // 确保删除键和其他键正常处理
            if (keyEvent->key() == Qt::Key_Backspace || keyEvent->key() == Qt::Key_Delete) {
                return false; // 将事件传递给 QLineEdit 的默认处理
            }
        }
    }

    if (event->type() == QEvent::MouseButtonPress) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);

        if (cityDialog && cityDialog->isVisible()) {
            // 检查鼠标点击是否在 cityDialog 或 QLineEdit 上
            bool clickedOutsideDialog = !cityDialog->geometry().contains(mouseEvent->globalPos());
            bool clickedOutsideLineEdit = !ui->DepartEdit->geometry().contains(
                ui->DepartEdit->mapFromGlobal(mouseEvent->globalPos()));
            bool clickedOutsideLineEdit2 = !ui->ApartEdit->geometry().contains(
                ui->ApartEdit->mapFromGlobal(mouseEvent->globalPos()));

            // 如果点击不在 dialog 或 lineEdit 上，则隐藏 dialog 并清除文字选中
            if (clickedOutsideDialog && clickedOutsideLineEdit) {
                cityDialog->hide();
                ui->DepartEdit->deselect();
            }
            if (clickedOutsideDialog && clickedOutsideLineEdit2) {
                cityDialog->hide();
                ui->ApartEdit->deselect();
            }
        }
    }

    return QWidget::eventFilter(watched, event); // 保持默认处理
}


